package com.achievo.know.application.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.achievo.know.application.FaqApplication;
import com.achievo.know.application.NewsApplication;
import com.achievo.know.component.impl.FileManagerConfig;
import com.achievo.know.domain.FileAttachment;
import com.achievo.know.domain.FileAttachmentRepository;
import com.achievo.know.domain.FileRepository;
import com.achievo.know.domain.News;
import com.achievo.know.domain.NewsContent;
import com.achievo.know.domain.NewsRepository;
import com.achievo.know.domain.TempAttachment;
import com.achievo.know.domain.User;
import com.achievo.know.domain.UserFavorite;
import com.achievo.know.domain.UserRepository;
import com.achievo.know.pojo.Constants;
import com.achievo.know.pojo.FileHandle;
import com.achievo.know.pojo.SearchParam;
import com.dayatang.querychannel.service.QueryChannelService;
import com.dayatang.querychannel.support.Page;


@Service
public class NewsApplicationImpl implements NewsApplication {
	
	@Autowired
	private NewsRepository newsRepository;
	
	@Autowired
	private QueryChannelService queryChannel;
	
	@Autowired
	private FileAttachmentRepository fileAttachmentRepository;
	
	@Autowired
	private FileRepository fileRepository;
	
	@Autowired
	private FaqApplication faqApplication;
	
	@Autowired
	private UserRepository userRepository;
	

	
	public void setUserRepository(UserRepository userRepository) {
		this.userRepository = userRepository;
	}

	public FaqApplication getFaqApplication() {
		return faqApplication;
	}

	public void setFaqApplication(FaqApplication faqApplication) {
		this.faqApplication = faqApplication;
	}

	public FileRepository getFileRepository() {
		return fileRepository;
	}

	public void setFileRepository(FileRepository fileRepository) {
		this.fileRepository = fileRepository;
	}

	public FileAttachmentRepository getFileAttachmentRepository() {
		return fileAttachmentRepository;
	}

	public void setFileAttachmentRepository(
			FileAttachmentRepository fileAttachmentRepository) {
		this.fileAttachmentRepository = fileAttachmentRepository;
	}

	@Override
	public Page<News> queryPage(List<Long> cateIds,int currentPage, int pageSize,SearchParam params, boolean isSuper) {
		//默认按发布日期排序
		StringBuilder hql=new StringBuilder();
		hql.append("select n from News n ");
		List<Object> param=new ArrayList<Object>();
		if(params!=null){
			if(StringUtils.isNotEmpty(params.getAreaName()) && !"-1".equals(params.getAreaName())){
				hql.append(" join n.areas as area where area.id=? ");
				param.add(Long.parseLong(params.getAreaName()));
			}
			else{
				hql.append(" where 1=1 ");
			}
		}
		if(!isSuper){
			if(cateIds!=null && cateIds.size()>0){
				StringBuilder cb=new StringBuilder();
				for(Long cateId:cateIds){
					cb.append(cateId).append(",");
				}
				if(cb.length()>0){
					cb.deleteCharAt(cb.length()-1);
					hql.append(" and n.categoryId in (").append(cb.toString()).append(")");
				}
			}else{
				hql.append(" and 1!=1 ");
			}
		}
		if(params!=null){
			if(StringUtils.isNotEmpty(params.getTitle())){
				hql.append(" and n.title like ?");
				param.add("%"+params.getTitle()+"%");
			}
		}
		hql.append(" order by n.position desc");
		//参数
		return queryChannel.queryPagedResultByPageNo(hql.toString(), param.toArray(), currentPage, pageSize);
	}
	
	@Override
	@Transactional
	public void add(News news) {
		news.setPublishTime(new Date());
		int position=newsRepository.getMaxPosition();
		news.setPosition(position+1);
		newsRepository.save(news);
		Iterator<NewsContent> conts= news.getContent().iterator();
		while(conts.hasNext()){
			NewsContent c=conts.next();
			c.add();
		}
		Iterator<FileAttachment> atts= news.getAttachments().iterator();
		while(atts.hasNext()){
			FileAttachment a=atts.next();
			a.setFkId(news.getId());
			a.setFkType(2);//NEWS
			a.add();
			FileHandle.move(config.getUploadFileStoreDirectory(), config.getPersistFileStoreDirectory(), a);
		}
		FileAttachment image= news.getNewsImage();
		if(image!=null){
			image.setFkId(news.getId());
			image.setFkType(3);//IMAGE
			image.add();
			FileHandle.move(config.getUploadFileStoreDirectory(), config.getImageStoreDirectory(), image);
		}
	}
	

	@Override
	@Transactional
	public News showNews(long newsId,boolean add) {
		News n=get(newsId);
		List<FileAttachment> attachments=fileAttachmentRepository.listAttachment(n.getId(),2);
		//List<Faq> faqs=faqApplication.getNewsFaq(newsId);
		n.setAttachments(attachments);
		List<FileAttachment> image=fileAttachmentRepository.listAttachment(n.getId(),3);
		if(image.size()>0)
			n.setNewsImage(image.get(0));
		if(add)
			n.addBrowserSum();
		//n.setFaqs(faqs);
		return n;
	}
	
	@Override
	@Transactional
	public News showEditNews(long newsId, String tempFileId,String tempImageId) {
		News n=get(newsId);
		List<FileAttachment> attachments=fileAttachmentRepository.listAttachment(n.getId(),2);
		n.setAttachments(attachments);
		//n.addBrowserSum();
		for(FileAttachment a:attachments){
			TempAttachment temp=new TempAttachment();
			temp.setAttachName(a.getAttachName());
			temp.setAttachPath(a.getAttachPath());
			temp.setAttachSize(a.getAttachSize());
			temp.setAttachType(a.getAttachType().getName());
			temp.setTempFileId(tempFileId);
			temp.setGuid(a.getGuid());
			temp.setFkType(a.getFkType());
			if(StringUtils.isNotEmpty(a.getPhotoName())){
				String guid=FilenameUtils.getBaseName(a.getPhotoName());
				if(StringUtils.isNotEmpty(guid)){
					TempAttachment attIcon=fileRepository.getTempByGuid(guid);
					if(attIcon==null){
						attIcon=new TempAttachment();
						attIcon.setAttachName(a.getAttachName());
						attIcon.setAttachPath(a.getAttachPath());
						attIcon.setAttachType(FilenameUtils.getExtension(a.getPhotoName()));
						attIcon.setAttachSize(0);
						attIcon.setTempFileId(a.getGuid());
						attIcon.setGuid(guid);
						attIcon.setFkType(4);
						fileRepository.addTempAttachment(attIcon);
					}
					java.io.File ofile=null;
					try {
						ofile=new java.io.File(config.getImageStoreDirectory()+"/"+attIcon.getAttachPath()+a.getPhotoName());
						java.io.File path=new java.io.File(config.getUploadFileStoreDirectory()+"/"+attIcon.getAttachPath());
						if(!path.exists()){
							FileUtils.forceMkdir(path);
						}
						if(ofile.exists())
							FileUtils.copyFileToDirectory(ofile,path, true);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
			fileRepository.addTempAttachment(temp);
		}
		List<FileAttachment> images=fileAttachmentRepository.listAttachment(n.getId(),3);
		if(images.size()>0)
			n.setNewsImage(images.get(0));
		for(FileAttachment a:images){
			TempAttachment temp=new TempAttachment();
			temp.setAttachName(a.getAttachName());
			temp.setAttachPath(a.getAttachPath());
			temp.setAttachSize(a.getAttachSize());
			temp.setAttachType(a.getAttachType().getName());
			temp.setTempFileId(tempImageId);
			temp.setGuid(a.getGuid());
			temp.setFkType(a.getFkType());
			FileHandle.copy(config.getImageStoreDirectory(), config.getUploadFileStoreDirectory(), a);
			fileRepository.addTempAttachment(temp);
		}
		return n;
	}

	
	@Override
	@Transactional
	public void changePosition(News onew, News dnew) {
		int p=onew.getPosition();
		onew.setPosition(dnew.getPosition());
		dnew.setPosition(p);
		newsRepository.save(onew);
		newsRepository.save(dnew);
		
	}
	
	@Override
	@Transactional
	public void setSugest(String[] idArr, Date sugestDate) {
		for(String idStr:idArr){
			News n=newsRepository.get(Long.parseLong(idStr));
			if(n!=null){
				n.setSugestTime(sugestDate);
				newsRepository.save(n);
			}
		}
		
	}
	
	

	@Override
	public Long getLid(Long areaId, Long id) {
		return newsRepository.getLid(areaId, id);
	}
	
	@Override
	public Long getRid(Long areaId, Long id) {
		return newsRepository.getRid(areaId, id);
	}
	
	@Override
	public Long getTop(Long areaId) {
		return newsRepository.getTop(areaId);
	}
	
	@Override
	public Long getLid(Long id) {
		return newsRepository.getLid(id);
	}

	@Override
	public Long getRid(Long id) {
		return newsRepository.getRid(id);
	}

	@Override
	public Long getTop() {
		return newsRepository.getTop();
	}
	
	

	@Override
	@Transactional
	public void beforePosition(News onew,String ids) {
		News nnew=newsRepository.get(Long.parseLong(ids));
		newsRepository.beforePosition(onew,nnew);
		
	}
	

	@Override
	@Transactional
	public void addFavorite(UserFavorite uf, String userId) {
		User user=userRepository.get(userId);
		uf.setUserId(user.getId());
		uf.add();
	}
	

	@Override
	public Page<News> queryMyFavorite(String userId, int currentPage,
			int pageSize) {
		String hql="select new News(n.id,n.title,n.category,uf.addTime) from News n ,User u,UserFavorite uf where n.id=uf.fileId and u.id=uf.userId and u.username=? order by n.publishTime desc ";
		Object[] params=new Object[]{userId};
		return queryChannel.queryPagedResultByPageNo(hql, params, currentPage, pageSize);
	}
	

	@Override
	public void batchDeleteFavorite(String[] idArr) {
		newsRepository.batchDeleteFavorite(idArr);
	}

	@Override
	@Transactional
	public void updateNews(News onew) {
		newsRepository.save(onew);
	}

	@Override
	@Transactional
	public void edit(News news) {
		News n=showNews(news.getId(),false);
		//n.setBrowserNum(news.getBrowserNum());
		n.setCanFaq(news.isCanFaq());
		n.setCategory(news.getCategory());
		n.setDesc(news.getDesc());
		//n.setFaqSum(news.getFaqSum());
		n.setCanDown(news.isCanDown());
		n.setAttachPosition(news.getAttachPosition());
		n.setKeyword(news.getKeyword());
		n.setTitle(news.getTitle());
		n.setEditTime(new Date());
		n.setEditUser(news.getEditUser());
		n.setCategoryId(news.getCategoryId());
		n.setPublishUserName(news.getPublishUserName());
		Iterator<NewsContent> conts= n.getContent().iterator();
		while(conts.hasNext()){
			NewsContent c=conts.next();
			NewsContent t=news.getContent().iterator().next();
			if(t!=null){
				c.setContent(t.getContent());
				c.add();
				break;
			}
		}
		List<FileAttachment> atts= n.getAttachments();
		List<FileAttachment> attstemp= news.getAttachments();
		for(FileAttachment t:atts){
			FileAttachment temp=in(attstemp,t);
			if(temp==null){
				t.delete();
			}else{
				t.setPhotoName(temp.getPhotoName());
				t.setFkId(news.getId());
				t.setFkType(2);//NEWS
				t.save();
			}
		}
		for(FileAttachment t:attstemp){
			FileAttachment temp=in(atts,t);
			if(temp==null){
				t.setFkId(news.getId());
				t.setFkType(2);//NEWS
				t.add();
				FileHandle.move(config.getUploadFileStoreDirectory(), config.getPersistFileStoreDirectory(), t);
			}
		}
		FileAttachment image=n.getNewsImage();
		if(image==null){//原来没有，增加
			if(news.getNewsImage()!=null){
				image=news.getNewsImage();
				image.setFkId(news.getId());
				image.setFkType(3);//IMAGE
				image.add();
				FileHandle.move(config.getUploadFileStoreDirectory(), config.getImageStoreDirectory(), image);
			}
		}else{//原来有
			if(news.getNewsImage()!=null){//删除原来的，重新建
				image.delete();
				image=news.getNewsImage();
				image.setFkId(news.getId());
				image.setFkType(3);//IMAGE
				image.add();
				FileHandle.move(config.getUploadFileStoreDirectory(), config.getImageStoreDirectory(), image);
			}else{//删除
				image.delete();
			}
		}
		n.setAreas(news.getAreas());
		newsRepository.save(n);
		
	}
	
	public FileAttachment in(List<FileAttachment> atts,FileAttachment a){
		for(FileAttachment att:atts){
			if(att.getGuid().equals(a.getGuid())){
				return att;
			}
		}
		return null;
	}

	@Override
	public News get(Long id) {
		return newsRepository.get(id);
	}

	@Override
	@Transactional
	public void remove(News n) {
		newsRepository.remove(n);
	}
	
	@Override
	@Transactional
	public void batchDelete(String[] idArr) {
		newsRepository.batchDelete(idArr);
	}

	public NewsRepository getNewsRepository() {
		return newsRepository;
	}

	public void setNewsRepository(NewsRepository newsRepository) {
		this.newsRepository = newsRepository;
	}

	public QueryChannelService getQueryChannel() {
		return queryChannel;
	}

	public void setQueryChannel(QueryChannelService queryChannel) {
		this.queryChannel = queryChannel;
	}

	@Autowired
    private FileManagerConfig config;




	public FileManagerConfig getConfig() {
		return config;
	}

	public void setConfig(FileManagerConfig config) {
		this.config = config;
	}
	
	
	
	
}
